/*
 * @Author: yangni 920556271@qq.com
 * @Date: 2024-04-29 10:47:39
 * @LastEditors: yangni 920556271@qq.com
 * @LastEditTime: 2024-04-29 13:26:25
 * @FilePath: /yt-devops/lib/pages/amap/widget/amap_widget.dart
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:native_dart_package/http/request/exception/api_exception.dart';
import 'package:native_dart_package/loading/loading_util.dart';
import 'package:xbr_gaode_amap/amap/amap_flutter_map.dart';
import 'package:xbr_gaode_amap/amap/src/types/bitmap.dart';
import 'package:xbr_gaode_amap/amap/src/types/camera.dart';
import 'package:xbr_gaode_amap/amap/src/types/marker.dart';
import 'package:xbr_gaode_amap/amap/src/types/ui.dart';
import 'package:xbr_gaode_amap/base/amap_flutter_base.dart';
import 'package:xbr_gaode_amap/core/flat_marker.dart';
import 'package:xbr_gaode_amap/xbr_gaode_amap.dart';
import 'package:xbr_gaode_search/core/lat_lng.dart';
import 'package:xbr_gaode_search/entity/input_tip_result.dart';
import 'package:xbr_gaode_search/xbr_gaode_search.dart';
import 'package:yt_devops/components/log_utils.dart';
import 'package:yt_devops/model/amap_poi.dart';
import 'package:yt_devops/pages/amap/map_const_config.dart';
import 'package:yt_devops/resources/resources.dart';
import 'package:yt_devops/resources/str_res_keys.dart';
import 'package:yt_devops/services/map/map_services.dart';
import 'package:yt_devops/styles/styles.dart';
import 'package:yt_devops/utils/func_utils.dart';

class AmapWidget extends StatefulWidget {
  final LatLng position;

  final Function(AmapPoi)? onPositionShow;

  const AmapWidget({required this.position, this.onPositionShow, super.key});

  @override
  State<AmapWidget> createState() => AmapWidgetState();
}

class AmapWidgetState extends State<AmapWidget> {
  late AMapController amapController;

  late LatLng _position;

  Marker? marker;

  @override
  void initState() {
    XbrAmapSearch.initKey(
        androidAppKey: MapConstConfig.amapApiKeys.androidKey,
        iosAppKey: MapConstConfig.amapApiKeys.iosKey);
    XbrAmapSearch.updatePrivacyAgree(hasAgree: true);
    XbrAmapSearch.updatePrivacyShow(hasShow: true, hasContains: true);
    _position = widget.position;
    setPositionMarker();
    super.initState();
  }

  void didupdateWidget(covariant AmapWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    _position = widget.position;
    setPositionMarker();
  }

  @override
  void dispose() {
    super.dispose();
  }

  void setPositionMarker() async {
    var icon = await BitmapDescriptor.fromAssetImage(
      const ImageConfiguration(
        size: Size(32, 32),
        devicePixelRatio: 3,
      ),
      ImageAssets.mapMarker,
      mipmaps: false,
    );

    ///利用UI控制器将定位绘制到地图上
    marker = FlatMarker(
      icon: icon,
      position: _position,
      flat: true, //flat是将图片贴在地图上，跟随真实方向旋转
      anchor: Offset(0.5, 0.5),
      // infoWindow: InfoWindow(title: "当前位置:", snippet: addr),
      onTap: (argument) {
        Log.d('FlatMarker===  $argument');
        onMapClicked(Get.context!, _position);
      },
    );

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return AMapWidget(
      compassEnabled: true,
      initialCameraPosition: CameraPosition(target: _position),
      myLocationStyleOptions: MyLocationStyleOptions(true),
      privacyStatement: XbrGaodeAmap.instace().statement,
      apiKey: XbrGaodeAmap.instace().apikey,
      onMapCreated: onMapCreated,
      onPoiTouched: (AMapPoi poi) {
        if (poi.latLng != null) {
          onMapClicked(context, poi.latLng!);
        }
      },
      onTap: (latLng) => onMapClicked(context, latLng),
      scaleEnabled: false,
      markers: marker == null ? {} : {marker!},
    );
  }

  Future<void> onMapCreated(AMapController controller) async {
    amapController = controller;
  }

  FutureOr<void> onMapClicked(BuildContext context, LatLng latLng) async {
    Log.d('onMapClicked==');

    showLoading(toast: ResKey.loading.tr);
    Future.delayed(const Duration(seconds: 10), () {
      if (EasyLoading.isShow) {
        dismissLoading();
        FuncUtils.requestTipsDislog(
            Get.context!, ResKey.unableGetAddress.tr, false,
            duration: const Duration(seconds: 2));
      }
    });
    AmapPoi? poi = await geoLatng(latLng);
    dismissLoading();
    if (poi != null) {
      showTargetLocation(poi);
    }
  }

  Future<AmapPoi?> geoLatng(LatLng? latLng) async {
    AmapPoi? poi;
    if (latLng == null) {
      FuncUtils.requestTipsDislog(
          Get.context, ResKey.addressResolutionFailed.tr, false,
          duration: const Duration(seconds: 2));
      dismissLoading();
      return null;
    }
    poi = await MapServices.geoAmapLatng(
        context, LatLngModel(latLng.latitude, latLng.longitude));
    return poi;
  }

  void searchAroundAddress(BuildContext context, String text) async {
    showLoading(toast: ResKey.loading.tr);
    try {
      var poiList = await MapServices.searchAmpPoi(
              LatLngModel(_position.latitude, _position.longitude), text) ??
          [];

      // ignore: use_build_context_synchronously
      FocusScope.of(context).requestFocus(FocusNode());
      // ignore: use_build_context_synchronously
      showModalBottomSheet(
        context: context,
        backgroundColor: Colors.transparent,
        builder: (context) => Container(
          padding: EdgeInsets.fromLTRB(20.w, 20.h, 20.w, 16.h),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(10.w),
            color: Colors.white,
          ),
          height: 383.h,
          child: ListView.separated(
            itemCount: poiList.length,
            itemBuilder: (context, index) => InkWell(
              onTap: () async {
                Get.back();
                showTargetLocation(poiList[index]);
              },
              child: Column(children: <Widget>[
                Container(
                  margin: const EdgeInsets.only(top: 8, bottom: 5, left: 10),
                  child: Row(
                    children: <Widget>[
                      const Icon(
                        Icons.place,
                        size: 20.0,
                      ),
                      Text(poiList[index].name ?? '',
                          style: const TextStyle(
                            fontSize: 16,
                          ))
                    ],
                  ),
                ),
                Container(
                  margin: const EdgeInsets.only(top: 5, bottom: 5, left: 18),
                  alignment: Alignment.centerLeft,
                  child: Text(
                    poiList[index].formattedAddress ?? '',
                    style: const TextStyle(
                      fontSize: 14,
                      color: Color(0xFF646464),
                    ),
                  ),
                ),
              ]),
            ),
            separatorBuilder: (BuildContext context, int index) {
              return const Divider(color: Colour.dividerColor);
            },
          ),
        ),
      );
    } catch (e) {
      String? tip;
      if (e is ApiException) {
        tip = e.message;
      }
      FuncUtils.requestTipsDislog(
          context, tip ?? ResKey.unableSearchPositions.tr, false,
          duration: const Duration(seconds: 2));
    } finally {
      dismissLoading();
    }
  }

  showTargetLocation(AmapPoi poi) async {
    setState(() {
      _position = LatLng(poi.latitude, poi.longitude);
    });

    setPositionMarker();

    await amapController.moveCamera(CameraUpdate.newLatLngZoom(_position, 16),
        duration: 0);

    widget.onPositionShow?.call(poi);
  }
}
